package com.unknow.first.dapp.admin.account.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.lianziyou.chain.common.api.CommonPage;
import com.lianziyou.chain.common.api.CommonParam;
import com.lianziyou.chain.common.api.CommonResult;
import com.unknow.first.dapp.admin.account.constants.AccountConstants;
import com.unknow.first.dapp.admin.account.constants.ITradeTypeEnum;
import com.unknow.first.dapp.admin.account.dto.AddressAccountDetailQueryDTO;
import com.unknow.first.dapp.admin.account.dto.AddressTransferDTO;
import com.unknow.first.dapp.admin.account.dto.AddressTransferRecordQueryDTO;
import com.unknow.first.dapp.admin.account.mapper.AddressAccountDetail;
import com.unknow.first.dapp.admin.account.mapper.AddressAccountInfo;
import com.unknow.first.dapp.admin.account.mapper.AddressTransfer;
import com.unknow.first.dapp.admin.account.mapper.AddressWithdraw;
import com.unknow.first.dapp.admin.account.service.*;
import com.unknow.first.dapp.admin.account.vo.WithdrawVO;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.cloud.annotation.AuthLog;
import org.cloud.annotation.SystemResource;
import org.cloud.constant.CoreConstant.AuthMethod;
import org.cloud.context.RequestContextManager;
import org.cloud.entity.LoginUserDetails;
import org.cloud.exception.BusinessException;
import org.cloud.utils.CommonUtil;
import org.cloud.utils.GoogleAuthenticatorUtil;
import org.cloud.utils.MyBatisPlusUtil;
import org.cloud.vo.CommonApiResult;
import org.cloud.vo.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/address/account")
@Slf4j
@SystemResource(path = "/address/account")
@Api(value = "APP:地址账户信息管理接口", tags = "APP:地址账户信息管理接口")
public class AddressAccountController {

    @Autowired
    AddressAccountInfoService addressAccountInfoService;

    @Autowired
    AddressAccountDetailService addressAccountDetailService;
    @Autowired
    private AddressWithdrawService addressWithdrawService;


    @GetMapping("/queryAccountInfoByAddress")
    @SystemResource(value = "/queryAccountInfoByAddress", description = "查询地址信息", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("获取用户账户列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "address", value = "地址信息", paramType = "query"),
            @ApiImplicitParam(name = "coinId", value = "币种ID", paramType = "query"),
            @ApiImplicitParam(name = "accountStatus", value = "账户状态(10：可用 -10：禁用)", paramType = "query"),})
    public CommonApiResult<List<AddressAccountInfo>> queryAccountInfoByAddress(@ApiParam(hidden = true) @RequestParam Map<String, Object> params)
            throws Exception {
        params.put("address", RequestContextManager.single().getRequestContext().getUser().getUsername());
        return CommonApiResult.createSuccessResult(addressAccountInfoService.queryAccountInfoByAddress(params));
    }

    @GetMapping("/queryAccountDetailByAddress")
    @SystemResource(value = "/queryAccountDetailByAddress", description = "查询地址交易信息", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("查询地址交易信息")
    public CommonApiResult<CommonPage<AddressAccountDetail>> queryAccountDetailByAddress(CommonParam pageParam,
                                                                                         AddressAccountDetailQueryDTO accountDetailQueryDTO) throws Exception {
        CommonApiResult<CommonPage<AddressAccountDetail>> successResult = CommonApiResult.createSuccessResult();
        QueryWrapper<AddressAccountDetail> queryWrapper = MyBatisPlusUtil.single().getPredicate(accountDetailQueryDTO);
        String userName = RequestContextManager.single().getRequestContext().getUser().getUsername();
        queryWrapper.eq("address", userName);
        queryWrapper.select("sum(amount) sum_of_amount");
        AddressAccountDetail accountDetail = addressAccountDetailService.getOne(queryWrapper);
        successResult.getOtherInfo().put("sumOfAmount", accountDetail == null ? BigDecimal.ZERO : accountDetail.getSumOfAmount());
        queryWrapper = MyBatisPlusUtil.single().getPredicate(accountDetailQueryDTO);
        queryWrapper
                .eq("address", userName)
                .lambda()
                .eq(AddressAccountDetail::getIsShow, AccountConstants.AccountDetailIsShow.SHOW.value);
        CommonPage<AddressAccountDetail> result = addressAccountDetailService.findListByPage(pageParam.getPage(), pageParam.getLimit(), pageParam.getSorts(),
                queryWrapper);
        successResult.setData(result);
        return successResult;
    }

    @GetMapping("/queryAccountDetailCollectByAddress")
    @SystemResource(value = "/queryAccountDetailCollectByAddress", description = "查询地址交易信息汇总金额", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("查询地址交易信息汇总金额")
    public CommonApiResult<List<Map<String, Object>>> queryAccountDetailCollectByAddress(CommonParam pageParam,
                                                                                         AddressAccountDetailQueryDTO accountDetailQueryDTO) throws Exception {
        //币种ID不能为空，否则数据没有参考意义
        Assert.isTrue(accountDetailQueryDTO.getCoinId() != null, "AddressAccount.error.coinidNotNull");
        CommonApiResult<List<Map<String, Object>>> successResult = CommonApiResult.createSuccessResult();
        QueryWrapper<AddressAccountDetail> queryWrapper = MyBatisPlusUtil.single().getPredicate(accountDetailQueryDTO);
        String userName = RequestContextManager.single().getRequestContext().getUser().getUsername();
        queryWrapper = MyBatisPlusUtil.single().getPredicate(accountDetailQueryDTO);
//        if (ObjectUtils.isEmpty(accountDetailQueryDTO.getAddress())){
        queryWrapper.eq("address", userName);
//        }
        queryWrapper.select("DATE_FORMAT(CREATED_DATE,'%Y-%m-%d') as date", "sum(amount) as totalAmount");
        queryWrapper.last(" GROUP BY DATE_FORMAT(CREATED_DATE,'%Y-%m-%d') order by date desc");
        PageHelper.startPage(pageParam.getPage(), pageParam.getLimit());
        List<Map<String, Object>> list = addressAccountDetailService.getBaseMapper().selectMaps(queryWrapper);
        successResult.setData(list);
        return successResult;
    }

    @AuthLog(bizType = AccountConstants.LOG_BIZ_TYPE, desc = "创建提现订单")
    @PostMapping("/createWithDraw")
    @SystemResource(value = "/createWithDraw", description = "用户创建提现订单", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("创建提现订单")
    public CommonResult<AddressWithdraw> createWithDraw(@RequestBody WithdrawVO withdrawVO) throws Exception {

        if (CommonUtil.single().getEnv("system.address-account.withdraw.mfa.enabled", Boolean.FALSE, Boolean.class)) {
            String googleSecret = GoogleAuthenticatorUtil.single().getCurrentUserVerifyKey();
            if (!GoogleAuthenticatorUtil.single().checkGoogleVerifyCode(googleSecret)) {
                throw new BusinessException("system.error.google.valid", 401);
            }
        }
        LoginUserDetails loginUserDetails = RequestContextManager.single().getRequestContext().getUser();
        Assert.isTrue(withdrawVO.getAmount().compareTo(BigDecimal.ZERO) > 0, "AddressAccount.error.amountTooSmall");
//        return CommonApiResult.createSuccessResult(addressAccountDetailService.createWithdraw(withdrawVO.getPayTo(), withdrawVO.getCoinId(), withdrawVO.getAmount()));
        return addressWithdrawService.withdraw(loginUserDetails.getUsername(), loginUserDetails.getUsername(), withdrawVO.getCoinId(), withdrawVO.getAmount());
    }

    @Autowired
    TradeTypeService tradeTypeService;

    @GetMapping("/listTradeType")
    @SystemResource(value = "/listTradeType", description = "查询交易类型列表", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("查询交易类型列表")
    public CommonApiResult<List<ITradeTypeEnum>> listTradeType() throws Exception {
        return CommonApiResult.createSuccessResult(tradeTypeService.listTradeType());
    }

    @Autowired
    private AddressTransferService addressTransferService;

    @AuthLog(bizType = AccountConstants.LOG_BIZ_TYPE, desc = "内部转账")
    @PostMapping("/transfer")
    @SystemResource(value = "/transfer", description = "内部转账", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("内部转账")
    public ResponseResult<?> transfer(@RequestBody AddressTransferDTO transferDTO) throws Exception {
        LoginUserDetails loginUserDetails = RequestContextManager.single().getRequestContext().getUser();
        return addressTransferService.transfer(transferDTO.getCoinId(), loginUserDetails.getUsername(), transferDTO.getTo(), transferDTO.getAmount(), null);
    }

    @GetMapping("/transfer/record")
    @SystemResource(value = "/transfer/record", description = "查询内部转账记录", authMethod = AuthMethod.ALLSYSTEMUSER)
    @ApiOperation("查询内部转账记录")
    public CommonApiResult<CommonPage<AddressTransfer>> transferRecord(AddressTransferRecordQueryDTO transferRecordQueryDTO, CommonParam commonParam) {
        LoginUserDetails loginUserDetails = RequestContextManager.single().getRequestContext().getUser();
        QueryWrapper<AddressTransfer> queryWrapper = MyBatisPlusUtil.single().getPredicate(transferRecordQueryDTO);
        LambdaQueryWrapper<AddressTransfer> lambdaQueryWrapper = queryWrapper
                .lambda()
                .and(qw -> {
                    qw.eq(AddressTransfer::getFromAddress, loginUserDetails.getUsername())
                            .or()
                            .eq(AddressTransfer::getToAddress, loginUserDetails.getUsername());
                })
                .orderByDesc(AddressTransfer::getCreatedDate);
        PageHelper.startPage(commonParam.getPage(), commonParam.getLimit());
        List<AddressTransfer> list = addressTransferService.list(lambdaQueryWrapper);
        return CommonApiResult.createSuccessResult(CommonPage.restPage(list));

    }


    @ApiOperation("查询用户提现记录")
    @GetMapping("/withdraw/record")
    @SystemResource(value = "/withdraw/record", description = "查询用户提现记录", authMethod = AuthMethod.ALLSYSTEMUSER)
    public CommonResult<CommonPage<AddressWithdraw>> withdrawList(@RequestParam(required = false) Integer coinId,
                                                                  CommonParam commonParam){
        LoginUserDetails loginUserDetails = RequestContextManager.single().getRequestContext().getUser();
        PageHelper.startPage(commonParam.getPage(), commonParam.getLimit());
        List<AddressWithdraw> list = addressWithdrawService.list(
                Wrappers.lambdaQuery(AddressWithdraw.class)
                        .eq(coinId != null, AddressWithdraw::getCoinId, coinId)
                        .eq(AddressWithdraw::getAddress, loginUserDetails.getUsername())
                        .last("ORDER BY FIELD(status, 20) desc, id desc")   //状态20（审核通过）排在前边，然后id降序
        );
        return CommonResult.success(CommonPage.restPage(list));
    }

}
